# -*- coding: utf-8 -*-
"""
@Time ： 2024/9/26 9:19
@Auth ： 周瑞东 Ryan.Zhou
@File ：global_state.py
"""
import os

import numpy as np
import queue

class Power:
    def __init__(self):
        # 软件启动后，在维护连接线程中，检测串口句柄是否存在
        # self.serial_port_is_existed = False
        # 通过判断serial_port_handler是否为None，来判断串口是否打开
        # self.serial_port_handler = None

        self.target_vid = 0x10C4
        self.target_pid = 0xEA60
        self.target_serial_number = "6075F407CCBBEA11A83B8EBE68AED703"
        self.power_is_started  = False


class E1682:
    def __init__(self):
        self.e1682_is_reachable_via_ping = False
        self.e1682_is_started  = False

        self.ip_addr_des = "192.168.1.250"
        self.ip_addr_src = "192.168.1.10"
        self.tcp_port = 6000

        self.SEND_BUF_SIZE = 4096  # 发送缓冲区
        self.RECV_BUF_SIZE = 10000000  # 接收缓冲区

        # 绘制曲线的历史长度
        # 因为采集卡的每一帧包含90个sample，所以历史长度应为90的倍数
        self.plot_history_length = 90 * 10

        self.tframe = 1  # 单次处理的TCP帧个数
        '''
        以下各通道缓冲，为单次处理的数据量，即每个通道，按照以下单位，进行数据更新
        '''
        self.Chw_0_temp = [0] * 90 * self.tframe
        self.Chw_1_temp = [0] * 90 * self.tframe
        self.Chw_2_temp = [0] * 90 * self.tframe
        self.Chw_3_temp = [0] * 90 * self.tframe
        self.Chw_4_temp = [0] * 90 * self.tframe
        self.Chw_5_temp = [0] * 90 * self.tframe
        self.Chw_6_temp = [0] * 90 * self.tframe
        self.Chw_7_temp = [0] * 90 * self.tframe
        self.Frame_num = [0] * 4

        # 特别注意，初始化的时候，必须为浮点数序列，否则会自动取整
        self.curve_data = np.zeros((8, 900))
        # self.curve_data = [[] for _ in range(8)]  # 创建一个包含8个空列表的列表
        # for i in range(8):
        #     self.curve_data[i].append([0.0] * 90 * 10)

        # 每90个数据做一次均值
        self.curve_data_aver90 = np.zeros((8, 900))
        '''
        array_position是一个循环数组，1-900，下一个循环变为2-902
        目的是为了跟踪缺陷在画布中的位置
        当识别一个缺陷后，为了避免重复识别和跟踪标注，需要记录缺陷的位置，如何记录？
        这里使用了一个array_position，发现缺陷时，根据缺陷在curve中的index，用这个index去对应array_position的一个值，
        随着采集卡采集到新数据，这个值在array_position中不断左移，但只要保存了缺陷的array pos value
        再用np.where查找该value在array_position中的位置，就能找到缺陷在画布中的位置
        '''
        self.array_position = np.arange(1, 901).reshape(1, 900)  # 创建一个 (1, 900) 数组
        self.array_position = np.tile(self.array_position, (8, 1))  # 复制到 (8, 900) 的形状
        self.array_pos_value_new = 901
        # print("初始数组:")
        # print(self.array_position[1])


        # self.chn0_curve_data = [0.0] * 90 * 10
        # self.chn1_curve_data = [0.0] * 90 * 10
        # self.chn2_curve_data = [0.0] * 90 * 10
        # self.chn3_curve_data = [0.0] * 90 * 10
        # self.chn4_curve_data = [0.0] * 90 * 10
        # self.chn5_curve_data = [0.0] * 90 * 10
        # self.chn6_curve_data = [0.0] * 90 * 10
        # self.chn7_curve_data = [0.0] * 90 * 10

        # Range_Mark=1，量程5V，Range_Mark=2，量程10V
        self.range_mark = 1
        self.counter0_num = [0] * 4
        self.counter1_num = [0] * 4
        self.digital_input_num = [0]

        self.tcp_que = queue.Queue(maxsize = 400)# tcp fifo

        self.sampling_update_interval = 0.5

class DataMan:
    def __init__(self):
        self.proj_path = os.getcwd()
        self.path_config_folder = "\\settings\\"
        self.path_database_file_path = "\\database\\frost_db_20241224"
        self.path_data_export_root = r"D:\data_export"
        self.vertical_section_size = 30
        self.flag_db_is_connected = False
        self.flag_cur_well_is_recording = False

class Common:
    def __init__(self):
        self.proj_path = os.getcwd()
        self.path_config_folder = "\\settings\\"
        self.debug = True
        # self.path_database_file_path = "\\database\\frost_db_20241224"

class GlobalState:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(GlobalState, cls).__new__(cls)

            # 初始化全局状态
            cls._instance.e1682 = E1682()
            cls._instance.common = Common()
            cls._instance.power = Power()
            cls._instance.data_man = DataMan()

        return cls._instance